#include "led.h"
#include "gpio.h"
#include <stdlib.h>

#define LEDR_PORT   GPIOB
#define LEDR_PIN    GPIO_PIN_8
#define LEDG_PORT   GPIOB
#define LEDG_PIN    GPIO_PIN_9
#define LEDB_PORT   GPIOC
#define LEDB_PIN    GPIO_PIN_15

#define LED_TASK_PERIOD 10U

/* 全系统全局变量 */
LEDObjectTypeDef led[3];
static LEDCtrlTypeDef ledr_ctrl_ququeHandle; /* LEDR 控制队列Handle */
static LEDCtrlTypeDef ledg_ctrl_ququeHandle; /* LEDG 控制队列Handle */
static LEDCtrlTypeDef ledb_ctrl_ququeHandle; /* LEDB 控制队列Handle */

static void led_set_pin(LEDObjectTypeDef *self, uint32_t level);   /* LED_SYS 灯写 IO 口接口 */
static int put_ctrl_block(LEDObjectTypeDef *self, LEDCtrlTypeDef *p);   /* 控制入队接口 */
static int get_ctrl_block(LEDObjectTypeDef *self, LEDCtrlTypeDef *p);   /* 控制出队接口 */

/**
  * @brief 初始化led相关内存、变量
  * @retval None.
*/
void led_init(void)
{
	/* 建立 LED1 控制队列 */
//	const osMessageQueueAttr_t ledr_ctrl_quque_attributes = { .name = "ledr_ctrl_quque" };
//	ledr_ctrl_ququeHandle = osMessageQueueNew (5, sizeof(LEDCtrlTypeDef), &ledr_ctrl_quque_attributes);
//	const osMessageQueueAttr_t ledg_ctrl_quque_attributes = { .name = "ledg_ctrl_quque" };
//	ledg_ctrl_ququeHandle = osMessageQueueNew (5, sizeof(LEDCtrlTypeDef), &ledg_ctrl_quque_attributes);
//    const osMessageQueueAttr_t ledb_ctrl_quque_attributes = { .name = "ledb_ctrl_quque" };
//	ledb_ctrl_ququeHandle = osMessageQueueNew (5, sizeof(LEDCtrlTypeDef), &ledb_ctrl_quque_attributes);
    
    
    
    for (uint8_t i = 0; i < 3; i++)
    {
        led_object_init(&led[i]);
        led[i].id = i + 1;
        led[i].set_pin = led_set_pin;
        led[i].get_ctrl_block = get_ctrl_block;
        led[i].put_ctrl_block = put_ctrl_block;
    }
	

   // packet_register_callback(&packet_controller, PACKET_FUNC_LED, packet_handler);
}

/**
  * @brief 定时器回调
  * @detials 定时刷新LED灯状态
  * @retval None.
  *
*/
void led_timer_callback(void *argument) {
    for (uint8_t i = 0; i < 3; i++)
    {
        led_task_handler(&led[i], LED_TASK_PERIOD);
    }
}


static void led_set_pin(LEDObjectTypeDef *self, uint32_t level)
{
    switch (self->id)
    {
        case 1:
            HAL_GPIO_WritePin(LEDR_PORT, LEDR_PIN, (GPIO_PinState)(level ^ 1u));
            break;
        case 2:
            HAL_GPIO_WritePin(LEDG_PORT, LEDG_PIN, (GPIO_PinState)(level ^ 1u));
            break;
        case 3:
            HAL_GPIO_WritePin(LEDB_PORT, LEDB_PIN, (GPIO_PinState)(level ^ 1u));
            break;
    }
    
}

static int8_t simulateQueuePut(LEDCtrlTypeDef *self, LEDCtrlTypeDef *p)
{
    self->data_effective = 1;
    self->repeat = p->repeat;
    self->ticks_on = p->ticks_on;
    self->ticks_off = p->ticks_off;
    return 0;
}

static int8_t simulateQueueGet(LEDCtrlTypeDef *self, LEDCtrlTypeDef *p)
{
    if (self->data_effective == 0)
    {
        return -1;
    }
    self->data_effective = 0;
    p->repeat = self->repeat;
    p->ticks_on = self->ticks_on;
    p->ticks_off = self->ticks_off;
    return 0;
}

/**
  * @brief LED控制队列入队接口
  * @param [in] p 要出队的控制参数结构体指针
  * @retval 0 成功
  * @retval !=0 失败 
  *
*/
static int put_ctrl_block(LEDObjectTypeDef *self, LEDCtrlTypeDef *p) {
    switch (self->id)
    {
        case 1:
            return (int)simulateQueuePut(&ledr_ctrl_ququeHandle, p);
        case 2:
            return (int)simulateQueuePut(&ledg_ctrl_ququeHandle, p);
        case 3:
            return (int)simulateQueuePut(&ledb_ctrl_ququeHandle, p);
        default:
            return -1;
    }
    
	
}

/**
  * @brief LED 控制队列出队接口
  * @param [out] p 出队数据的存储指针
  * @retval 0 成功
  * @retval !=0 失败 
  *
*/
static int get_ctrl_block(LEDObjectTypeDef *self, LEDCtrlTypeDef *p) {
    switch (self->id)
    {
        case 1:
            return (int)simulateQueueGet(&ledr_ctrl_ququeHandle, p);
        case 2:
            return (int)simulateQueueGet(&ledg_ctrl_ququeHandle, p);
        case 3:
            return (int)simulateQueueGet(&ledb_ctrl_ququeHandle, p);
        default:
            return -1;
    }
}
